#include <opus.h>
#include "Arduino.h"
#include "codec.h"

OpusEncoder *opus_encoder_;

void initCodec()
{
    int encoder_error;
    opus_encoder_ = opus_encoder_create(I2S_SAMPLE_RATE, AUDIO_OPUS_CHANNELS, OPUS_APPLICATION_AUDIO, &encoder_error);
    if (encoder_error != OPUS_OK)
    {
        Serial.printf("Failed to create OPUS encoder, error %d", encoder_error);
        return;
    }
    opus_encoder_ctl(opus_encoder_, OPUS_SET_BITRATE(AUDIO_OPUS_BITRATE));
    opus_encoder_ctl(opus_encoder_, OPUS_SET_COMPLEXITY(AUDIO_OPUS_COMPLEXITY));
    opus_encoder_ctl(opus_encoder_, OPUS_SET_SIGNAL(OPUS_SIGNAL_MUSIC));
    opus_encoder_ctl(opus_encoder_, OPUS_SET_VBR(1));
    opus_encoder_ctl(opus_encoder_, OPUS_SET_VBR_CONSTRAINT(1));
    opus_encoder_ctl(opus_encoder_, OPUS_SET_DTX(0));
    // opus_encoder_ctl(opus_encoder_, OPUS_SET_GAIN(40));
}

int encode(int16_t *pcm_samples, uint8_t *encoded_data, int max_bytes) {
    if (!opus_encoder_) {
        Serial.println("Opus encoder not initialized!");
        return -1;
    }
    UBaseType_t freeStack = uxTaskGetStackHighWaterMark(NULL);
//    Serial.printf("Free stack: %d bytes\n", uxTaskGetStackHighWaterMark(NULL) * 4);

    int encoded_size = opus_encode(opus_encoder_, pcm_samples, FRAME_SAMPLES, encoded_data, max_bytes);
    return encoded_size;
}